<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { useMessage, NModal, NForm, NFormItem, NInput, NUpload, NButton } from 'naive-ui'
import type {
  TalentItemType,
  CreateTalentPayloadType,
  UpdateTalentPayloadType
} from '@/types/api/talent'
import { createTalentApi, updateTalentApi } from '@/api/talent'
import type { FormInst, FormRules, UploadFileInfo } from 'naive-ui'
import { OSSUtil } from '@/utils/alioss'
import { TALENT_DIR } from '@/constants/biz'
import SectorSelect from '@/components/SectorSelect/index.vue'

const message = useMessage()

type PropsType = {
  type: 'create' | 'update'
  record: TalentItemType | null
  onOk?: Function
}
const props = defineProps<PropsType>()

const title = computed(() => (props.type === 'create' ? '新增' : '编辑'))
const showModal = ref(false)

const formRef = ref<FormInst | null>(null)
const formValue = ref<
  Omit<CreateTalentPayloadType, 'fileName' | 'etag' | 'sector'> & {
    fileList: UploadFileInfo[]
    sector: '1' | '2' | '3' | undefined
  }
>({
  name: '',
  fileList: [],
  phoneNumber: '',
  company: '',
  jobTitle: '',
  sector: undefined
})
const formRules: FormRules = {
  name: {
    required: true,
    message: '请输入姓名',
    trigger: ['input']
  },
  fileList: {
    required: true,
    message: '请选择文件',
    trigger: 'upload',
    validator: (rule: any, value: any) => value.length > 0
  },
  phoneNumber: {
    required: true,
    message: '请输入手机号',
    trigger: ['input']
  },
  company: {
    required: true,
    message: '请输入公司信息',
    trigger: ['input']
  },
  jobTitle: {
    required: true,
    message: '请输入岗位名称',
    trigger: ['input']
  },
  sector: {
    required: true,
    message: '请选择行业类型',
    trigger: ['change']
  }
}
const onUploadChange = () => {
  Promise.resolve().then(() => {
    formRef.value?.validate(
      () => {},
      (rule) => {
        return rule.trigger === 'upload'
      }
    )
  })
}

watch(showModal, (val) => {
  if (val) {
    // 弹窗打开
    const { record } = props
    if (record) {
      formValue.value.name = record.name
      formValue.value.phoneNumber = record.phoneNumber
      formValue.value.company = record.company
      formValue.value.jobTitle = record.jobTitle
      formValue.value.sector = record.sector.toString() as '1' | '2' | '3' | undefined
      formValue.value.fileList = [
        {
          id: record.id,
          name: record.fileName.replace(TALENT_DIR + '/', ''),
          status: 'finished'
        }
      ]
    } else {
      formValue.value.name = ''
      formValue.value.fileList = []
    }
  }
})

const handleOk = async () => {
  const { onOk, type, record } = props
  await formRef.value?.validate()
  const { name, fileList } = formValue.value
  // 如果存在file则上传
  const file = fileList[0].file
  const payload: CreateTalentPayloadType = {
    name,
    fileName: record?.fileName || '',
    etag: record?.etag || '',
    phoneNumber: formValue.value.phoneNumber,
    company: formValue.value.company,
    jobTitle: formValue.value.jobTitle,
    sector: formValue.value.sector ? (parseInt(formValue.value.sector) as 1 | 2 | 3) : 1
  }
  if (file) {
    const fileName = `${TALENT_DIR}/${file.name}`
    await OSSUtil.init('chenmingxu')
    try {
      const multipartUploadRes = await OSSUtil.multipartUpload(fileName, file, {
        parallel: 4,
        partSize: 1024 * 1024,
        progress: (p, cpt, res) => {
          console.log('上传进度: ', p, cpt, res)
        }
      })
      payload.fileName = multipartUploadRes.name
      payload.etag = JSON.parse(multipartUploadRes.etag)
    } catch (error: unknown) {
      let errorMessage = '上传文件失败'
      if (error instanceof Error) {
        errorMessage = `${errorMessage}: ${error.message}`
      }
      return message.error(errorMessage)
    }
  }

  if (type === 'create') {
    // 新增
    await createTalentApi(payload)
  } else {
    // 编辑
    const updatePayload: UpdateTalentPayloadType = {
      id: record!.id,
      ...payload
    }
    await updateTalentApi(updatePayload)
  }
  message.success(`${title.value}成功`)
  showModal.value = false
  onOk && onOk()
}

defineExpose({
  showModal
})
</script>

<template>
  <NModal
    v-model:show="showModal"
    :title="title"
    preset="dialog"
    positive-text="确认"
    negative-text="取消"
    @positiveClick="handleOk"
  >
    <div style="margin-top: 20px">
      <NForm ref="formRef" :model="formValue" :rules="formRules">
        <NFormItem label="姓名" path="name">
          <NInput v-model:value="formValue.name" placeholder="请输入姓名" :clearable="true" />
        </NFormItem>
        <NFormItem label="手机号" path="phoneNumber">
          <NInput
            v-model:value="formValue.phoneNumber"
            placeholder="请输入手机号"
            :clearable="true"
          />
        </NFormItem>
        <NFormItem label="公司信息" path="company">
          <NInput
            v-model:value="formValue.company"
            placeholder="请输入公司信息"
            :clearable="true"
          />
        </NFormItem>
        <NFormItem label="行业类型" path="sector">
          <SectorSelect v-model:value="formValue.sector" />
        </NFormItem>
        <NFormItem label="岗位名称" path="jobTitle">
          <NInput
            v-model:value="formValue.jobTitle"
            placeholder="请输入岗位名称"
            :clearable="true"
          />
        </NFormItem>
        <NFormItem label="上传简历" path="fileList">
          <NUpload
            v-model:file-list="formValue.fileList"
            accept=".pdf"
            :default-upload="false"
            :max="1"
            :on-change="onUploadChange"
          >
            <NButton>选择简历</NButton>
          </NUpload>
        </NFormItem>
      </NForm>
    </div>
  </NModal>
</template>

<style lang="scss" scoped></style>
